package Codage.Model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Decodage {

	private Map<String, String> translation;
	private ISPGraph sp;
	private List<Couple> list;
	
	public Decodage(ISPGraph sp) {
		this.translation = new HashMap<String,String>();
		for (String s : sp.getAllWords()) {
			this.translation.put(s, null);
		}
		this.sp = sp;
		list = new ArrayList<Couple>();
		list.add(new Couple(sp.getBeginState(),""));
	}
	
	private class Couple {
		private State state;
		private String mot;
		private Couple(State state, String mot) {
			this.state = state;
			this.mot = mot;
		}
	}
	
	public Map<String,String> addWord(String word) {
		StringBuffer mot = new StringBuffer(word);
		
		while (mot.length() > 0) {
			// A cause des IllegalConcurentException
			List<Couple> toAdd = new ArrayList<Couple>();
			List<Couple> toRemove = new ArrayList<Couple>();
			
			char c = mot.charAt(0);
			for (Couple couple : list) {
				State succ = couple.state.getAutomatSuccessor(c);
				if (succ == null) {
					toRemove.add(couple);
				} else {
					couple.state = succ;
					if (succ.isFinal()) {
						if (succ.getAllAutomatSuccessor().isEmpty()) {
							toRemove.add(couple);
						}
						toAdd.add(new Couple(sp.getBeginState(),couple.mot + translation.get(succ.getId())));
					}
				}
			}
			
			list.removeAll(toRemove);
			list.addAll(toAdd);
			
			mot.deleteCharAt(0);
		}
		
		Map<String,String> res = new HashMap<String,String>();
		for (Couple c : list) {
			res.put(c.mot, c.state.getId());
		}
		return res;
	}
	
	public boolean isValidDecodage() {
		if (this.translation == null) {
			return false;
		}
		for (String s : this.translation.keySet()) {
			if (this.translation.get(s) == null) {
				return false;
			}
		}
		return true;
	}

	public void putTranslation(String word,String translationWord) {
		if (!this.translation.containsKey(word)) {
			throw new IllegalStateException("impossible");
		}
		this.translation.put(word, translationWord);
	}
}
